home *** CD-ROM | disk | FTP | other *** search
- NAME ccsser
- ; File CCSSER.ASM
-
- ;CHINESE
- ifdef MSDOS
- include mssser.dat
- else
- include ccsser.dat
- endif
-
- code segment public 'code'
- extrn comnd:near, serrst:near, spack:near, rpack:near, init:near
- extrn read12:near, serini:near, read2:near, rpar:near, spar:near
- extrn rin21:near, rfile3:near, error1:near, clrfln:near
- extrn dodel:near, clearl:near, dodec: near, doenc:near
- extrn packlen:near, send11:near, errpack:near, pktsize:near
- extrn nak:near, rrinit:near, cmblnk:near, poscur:near, lnout:near
- extrn erpos:near, rprpos:near, clrmod:near, crun:near, ctlu:near
- extrn prompt:near, updrtr:near, prtfn:near, prtscr:near
- extrn strcat:near, strlen:near, strcpy:near, fparse:near, isfile:near
- extrn prtasz:near, ihosts:near, begtim:near, endtim:near
- extrn inptim:near, chktmo:near, pcwait:near
- assume cs:code, ds:datas, es:nothing
-
-
- ; BYE command - tell remote KERSRV to logout & exits to DOS.
-
- BYE PROC NEAR
- mov ah,cmcfm ; Parse a confirm
- call comnd
- jmp r
- mov remcmd,'L' ; Logout command letter
- call logo ; Tell the mainframe to logout
- jmp rskp ; Failed - don't exit
- mov flags.extflg,1 ; Set exit flag
- jmp rskp
- BYE ENDP
-
- ; FINISH - tell remote KERSRV to exit
-
- FINISH PROC NEAR
- mov ah,cmcfm ; Parse a confirm
- call comnd
- jmp r
- mov remcmd,'F' ; Finish command letter
- call logo
- jmp rskp
- jmp rskp
- FINISH ENDP
-
- ; LOGOUT - tell remote KERSRV to logout
-
- LOGOUT PROC NEAR
- mov ah,cmcfm
- call comnd ; Get a confirm
- jmp r
- mov remcmd,'L' ; Logout command letter
- call logo
- jmp rskp ; Go get another command whether we
- jmp rskp ; succeed or fail
- LOGOUT ENDP
-
- ; Common routine for FIN, LOGOUT, BYE
- LOGO PROC NEAR
- mov pack.numtry,0 ; Initialize count
- mov pack.numrtr,0 ; No retries yet
- mov ah,trans.chklen ; Don't forget the checksum length
- mov curchk,ah
- mov trans.chklen,1 ; Use one char for server functions
- call serini ; Initialize port
- jc logo2 ; c = failure
- call ihosts ; initialize the host
- mov diskio.string,0 ; clear local filename for stats
- call begtim ; start statistics counter
- logo1: cmp pack.state,'A' ; Did user type a ^C?
- je log2x ; e = yes, leave in failure state for Bye
- mov ah,pack.numtry
- cmp ah,maxtry ; Too many times?
- jl logo3 ; No, try it
- logo2: mov ah,prstr
- ; mov dx,offset erms18
- mcmsg erms18, cerms18
-
- int dos
- log2x:;;;call serrst ; Reset port
- mov ax,1 ; a send operation
- call endtim ; stop statistics counter
- mov ah,curchk
- mov trans.chklen,ah ; Restore value
- ret ; and exit in failure state for Bye
- logo3: inc pack.numtry ; Increment number of tries
- mov pack.seqnum,0 ; Packet number zero
- mov pack.datlen,1 ; One piece of data
- mov ah,remcmd ; get command letter ('L' or 'F')
- mov data,ah ; Logout the remote host
- mov cx,1 ; One piece of data
- call doenc ; Do encoding
- mov ah,'G' ; Generic command packet
- call spack
- jmp logo2 ; Tell user and die
- nop
- call rpack ; Get ACK (w/o screen msgs.)
- jmp logo1 ; Go try again
- nop
- push ax
- call dodec ; Decode packet
- pop ax
- cmp ah,'Y' ; ACK?
- jne logo4
- cmp pack.datlen,0 ; Any data in the ACK?
- je logo6 ; Nope - just return.
- mov ah,prstr ; output a cr/lf
- mov dx,offset crlf
- int dos
- mov di,offset data ; Where the reply is
- mov cx,pack.datlen ; How much data we have.
- call prtscr ; Print it on the screen
- jmp logo6 ; and exit
- logo4: cmp ah,'E' ; Error packet?
- je logo5 ; e = yes
- jmp logo1 ; try sending again
- logo5: call error1
- logo6: mov ax,1 ; a send operation
- call endtim ; stop statistics counter
- mov ah,curchk
- mov trans.chklen,ah ; Restore value
- jmp rskp ; use rskp so Bye succeeds
- LOGO ENDP
-
- ; GET command. Ask remote server to send the specified file(s)
- ; Queries for remote filename and optional local override path/filename
- GET PROC NEAR
- mov flags.nmoflg,0 ; Reset flags from fn parsing
- mov byte ptr locfil,0 ; clear, for safety
- mov byte ptr srvbuf,0 ; ditto
- mov flags.cxzflg,0 ; no Control-C typed yet
- mov cnt,0 ; count of filename chars
- mov bx,offset srvbuf ; Where to put text
- mov byte ptr [bx],0 ; clear for safety
- ; mov dx,offset filmsg ; In case user needs help
- mcmsg filmsg, cfilmsg
-
- mov ah,cmtxt ; filenames with embedded whitespace
- call comnd ; Get text or confirm
- jmp r ; Fail
- mov al,ah
- mov ah,0
- mov cnt,ax ; Remember number of chars we read
- cmp al,0 ; Read in any chars?
- je get1 ; e = no
- jmp get3b ; yes, analyze
- ; if empty line, ask for file names
- get1:
- ; mov dx,offset remfnm ; ask for remote name first
- mcmsg remfnm, cremfnm
-
- call prompt
- mov bx,offset srvbuf ; place for remote filename
- ; mov dx,offset frem ; the help message
- mcmsg frem, cfrem
-
- mov ah,cmtxt ; use this for embedded spaces
- call comnd ; get a filename
- jmp r
- mov al,ah
- mov ah,0
- mov cnt,ax ; remember number of chars read
- cmp al,0 ; count of entered chars
- je get1 ; e = none, try again
- get2:
- ; mov dx,offset lclfnm ; prompt for local filename
- mcmsg lclfnm, clclfnm
-
- call prompt
- get3: mov flags.nmoflg,0 ; assume no local override name
- ; mov bx,offset filhlp
- mcmsgb filhlp, cfilhlp
-
- mov dx,offset locfil ; complete local filename
- mov byte ptr locfil,0 ; clear, for safety
- mov ah,cmfile ; allow paths
- call comnd
- jmp r
- mov temp,ax
- mov ah,cmcfm
- call comnd
- jmp r
- mov ax,temp
- cmp ah,0 ; any text?
- je get2 ; e = none, ask again
- mov bx,offset locfil
- cmp byte ptr [bx],'#' ; Is first char a replacement for '?'
- jne get3a ; ne = no
- mov byte ptr [bx],'?' ; yes. Replace '#' by '?'
- get3a: mov al,ah ; number of chars in locfil according to cmd
- mov flags.nmoflg,al ; 0 = no override
- mov ah,0
- add bx,ax
- mov byte ptr [bx],0 ; force a termination null
-
- get3b: mov bx,offset srvbuf ; get remote filename address again
- cmp byte ptr [bx],'#' ; Is first char a replacement for '?' ?
- jne get4 ; ne = no
- mov byte ptr [bx],'?' ; yes. Replace '#' by '?'
-
- get4: cmp flags.cxzflg,0 ; ^X, ^Z, or ^C typed?
- je get5 ; e = no, keep going
- mov flags.cxzflg,0 ; clear the interrupt flag
- or errlev,2 ; say cannot receive
- or fsta.xstatus,2+80h ; set status failed + intervention
- mov kstatus,2 ; local status
- jmp rskp
- get5: call begtim ; start statistics
- cmp flags.destflg,2 ; receiving to screen?
- je get5a ; e = yes, skip screen stuff
- mov flags.xflg,0 ; no, reset x flag
- call init ; init screen
- get5a: call begtim ; start statistics
- mov kstatus,0 ; global status, success
- call ipack ; Send Initialize, 'I', packet
- jmp get8 ; Sorry can't do it
- nop
- mov cx,cnt ; Get back remote filename size
- mov pack.datlen,cx ; Need it here to send packet
- mov si,offset srvbuf ; Move from here
- mov di,offset data ; to here
- call strcpy ; copy from srvbuf to data
- mov di,offset fsta.xname ; to statistics remote name field
- call strcpy
- mov di,offset diskio.string ; and to here for prtfn
- call strcpy
- test flags.remflg,dquiet ; quiet display mode?
- jnz get6 ; nz = yes, don't print anything
- cmp flags.remflg,dserial ; serial mode display?
- je get6 ; e = yes, skip extra display item
- cmp flags.destflg,2 ; Receiving to screen?
- je get6 ; Yes skip screen stuff
- call prtfn ; print filename in data
- get6:
- call rrinit ; clear pack.xxx counters
- mov pack.numrtr,-1 ; No retries yet (gets incremented below)
- mov pack.state,'R' ; this is what state will be soon
- mov cx,pack.datlen ; Data size
- call doenc ; Encode data
- jnc get6a ; nc = success
- jmp get12 ; c = data could not all fit into packet
- get6a: mov ah,trans.chklen ; Don't forget the checksum length
- mov curchk,ah
- mov trans.chklen,1 ; Use one char for server functions
- get7: call updrtr
- cmp pack.state,'A' ; Did user type a ^C?
- je get9 ; Yes - just return to main loop
- mov ah,pack.numtry
- cmp ah,maxtry ; Too many times?
- jbe get10 ; Nope, try it
- get8: test flags.remflg,dquiet ; quiet display mode?
- jnz get9 ; nz = yes, no printing
- call erpos
- mov ah,prstr
- ; mov dx,offset erms18 ; Can't get init packet.
- mcmsg erms18, cerms18
-
- int dos
- or errlev,2 ; set DOS error level to cannot rcv
- or fsta.xstatus,2 ; set status
- mov kstatus,2 ; global status
- get9: test flags.remflg,dquiet+dserial ; quiet or serial display?
- jnz get9a ; nz = yes
- call clrmod
- call rprpos
- get9a: mov ah,curchk
- mov trans.chklen,ah ; Restore value
- xor ax,ax ; say this was a receive operation
- call endtim ; do statistics
- jmp rskp
- get10: inc pack.numtry ; Increment number of tries
- mov pack.seqnum,0 ; Start at packet zero
- call pktsize ; report packet size
- mov ah,'R' ; Receive init packet
- call spack ; Send the packet
- jmp get8 ; Tell user we can't do it
- nop
- call rpack ; Get ACK
- jmp get7 ; Got a NAK - try again
- nop
- push ax
- mov ah,curchk
- mov trans.chklen,ah ; Restore value
- pop ax
- mov flags.getflg,ah ; note this is a GET, use pkt type
- mov pack.state,'R' ; Set the state to receive initiate
- jmp read12 ; go join read code
- get12:
- ; mov dx,offset ermes6 ; Complain if filename is too long for pkt
- mcmsg ermes6, cermes6
-
- test flags.remflg,dquiet ; quiet display mode?
- jnz get13 ; nz = yes, no printing
- call erpos ; position cursor on formatted screen
- mov ah,prstr
- int dos
- get13: mov bx,dx ; point to message, for errpack
- call errpack ; tell the host we are quiting
- test flags.remflg,dserial ; serial display mode?
- jnz get14 ; nz = yes
- call clrmod ; clear mode line
- call rprpos ; Put prompt here
- get14: or errlev,2 ; set DOS error level to cannot rcv
- or fsta.xstatus,2 ; set status
- mov kstatus,2 ; global status
- jmp rskp
- GET ENDP
-
- ; server command
-
- SERVER PROC NEAR
- mov ah,cmfile ; get a word
- mov dx,offset srvbuf ; place to put text
- ; mov bx,offset inthlp ; help message
- mcmsgb inthlp, cinthlp
-
- call comnd ; get the pattern text
- jmp r ; nothing, complain
- nop
- mov temp,ax ; ah has byte count
- mov ah,cmcfm
- call comnd
- jmp r
- mov srvtime,0 ; assume not doing timed residence
- cmp byte ptr temp+1,0 ; time of day given?
- je serv0b ; e = no
- mov si,offset srvbuf
- cmp byte ptr [si],'0' ; numeric or colon?
- jb serv0 ; b = not proper time value
- cmp byte ptr [si],':' ; this covers the desired range
- ja serv0 ; a = no proper time value
- call inptim ; convert text to timeout tod
- jnc serv0a ; nc = no syntax errors in time
- serv0: ret ; else return now
-
- serv0a: mov srvtime,1 ; say doing timed residence
- serv0b: push es
- mov ax,ds
- mov es,ax ; address data segment
- mov al,flags.remflg ; get display mode flag
- push ax ; preserve for later
- ; Enable the line below if the server screen is to be quiet (clear),
- ; or make the line a comment if the server screen is to show file transfers
- ;===> mov flags.remflg,dquiet ; set quiet display flag if server
- ;
- or flags.remflg,dserver ; signify we are a server now
- mov ax,0 ; simulate empty parameter packet
- call spar ; and thus set our params to defaults
- mov ah,drpt ; force default repeat prefix char
- mov rptq,ah ; char be our active one
- test flags.remflg,dquiet ; quiet display?
- jnz serv1c ; nz = yes
- mov ah,prstr
- mov dx,offset crlf
- int dos
- test flags.remflg,dserial ; serial display?
- jnz serv1a ; nz = yes
- call cmblnk ; clear screen
- ; mov dx,scrser ; move cursor to top of screen
- mcscr scrser, cscrser
-
- call poscur
- serv1a: mov ah,prstr
- ; mov dx,offset infms1 ; say now in server mode
- mcmsg infms1, cinfms1
-
- int dos
- serv1c: mov ah,inichk ; set default checksum length
- mov curchk,ah ; save it here
-
- serv1: test flags.remflg,dquiet+dserial ; quiet or serial display?
- jnz serv1b ; nz = yes
- ; mov dx,scrsrm ; move cursor to server message area
- mcscr scrsrm, cscrsrm
-
- add dx,0100H ; look at line below (DOS does CR/LF first)
- call poscur
- call clearl ; and clear the line
- ; mov dx,scrsrm ; back to message line
- mcscr scrsrm, cscrsrm
-
- call poscur
- cmp flags.debug,0 ; debug display active?
- je serv1b ; e = no
- mov fmtdsp,1 ; yes, do formatted display
- serv1b: mov flags.nmoflg,0 ; clear, say no local override filenames
- mov flags.cxzflg,0 ; clear ^X, ^Z, ^C seen flag
- mov flags.xflg,0 ; reset X packet flag
- mov locfil,0 ; say no local filename [JB]
- mov ah,dtrans.seol ; restore default end-of-line char
- mov trans.seol,ah
- mov byte ptr srvbuf,0 ; plant terminator to clear
- mov trans.chklen,1 ; checksum len = 1
- mov pack.pktnum,0 ; pack number resets to 0
- mov pack.numtry,0 ; no retries yet
- mov al,trans.stime ; get current timeout interval
- mov curstim,al ; save current timeout interval
- add al,al ; triple it for server idle loop
- add al,curstim ; times three
- mov trans.stime,al ; use this longer interval in the idle loop
- call serini ; init serial line (send & receive reset it)
- jnc serv1e ; nc = success
- jmp serv5 ; c = failure
- serv1e: cmp srvtime,0 ; doing timed residence?
- je serv1d ; e = no
- call chktmo ; check for time to exit Server mode
- jnc serv1d ; nc = ok
- jmp serv5 ; c = timeout, exit server mode
- serv1d: call rpack ; get a packet
- jmp short serv2 ; no good, nak and continue
- nop
- push ax
- mov al,curstim ; get original timeout interval
- mov trans.stime,al ; restore timeout interval
- pop ax
- cmp ah,'I' ; never "decode" S, I, and A packets
- je serv3 ; its an I packet
- cmp ah,'S'
- je serv3
- cmp ah,'A'
- je serv3
- call dodec ; decode packet
- jmp short serv3 ; try to figure this out
-
- serv2: push ax
- mov al,curstim ; get original timeout interval
- mov trans.stime,al ; restore timeout interval
- pop ax
- cmp flags.cxzflg,'C' ; Control-C?
- jne serv2a ; ne = no
- mov flags.cxzflg,0 ; clear flag for later uses
- jmp serv5 ; and exit server mode
- serv2a: cmp ah,'T' ; packet type of time-out?
- jne serv2b ; ne = no
- mov al,srvtmo ; server timeout value
- mov trans.stime,al
- call nak ; nak the packet
- mov al,curstim
- mov trans.stime,al ; restore regular send timeout
- serv2b: mov al,curchk ; restore checksum length
- mov trans.chklen,al
- jmp serv1 ; and keep readiserv2 packets
-
- serv3: mov al,curchk ; restore checksum length
- mov trans.chklen,al
- push ds
- pop es ; set es to datas segment
- mov di,offset srvchr ; server characters
- mov cx,srvfln ; length of striserv2
- mov al,ah ; packet type
- cld
- repne scasb ; hunt for it
- je serv4 ; we know this one, go handle it
- cmp al,'N' ; received a Nak?
- je serv3a ; e = yes, ignore it
- ; mov bx,offset remms1 ; else give a message
- mcmsgb remms1, cremms1
-
- call errpack ; back to local kermit
- serv3a: jmp serv1 ; and keep lookiserv2 for a cmd
- serv4: sub di,offset srvchr+1 ; find offset, +1 for pre-increment
- shl di,1 ; convert to word index
- call srvfun[di] ; call the appropriate handler
- jmp serv5 ; someone wanted to exit..
- jmp serv1 ; else keep goiserv2 for more cmds
-
- serv5: mov al,curchk ; restore checksum length
- mov trans.chklen,al
- pop ax ; get this off stack
- test flags.remflg,dserial+dquiet ; serial or quiet display?
- jnz serv5a ; nz = yes
- call rprpos ; Put prompt here
- serv5a: mov flags.remflg,al ; restore old flag
- ;; call serrst ; reset serial handler
- mov fmtdsp,0 ; end of formatted display
- mov flags.cxzflg,0 ; clear this flag before exiting
- pop es ; restore register
- jmp rskp ; and return
- SERVER ENDP
-
- ; server commands
-
- ; srvsnd - receives a file that a remote kermit is sending
- srvsnd proc near
- mov bx,offset data
- mov ax,pack.datlen ; get number of data bytes
- call spar ; parse the send-init packet
- mov al,trans.chklen ; get negotiated checksum length
- mov curchk,al ; and remember it here
- call packlen ; figure max packet
- mov bx,offset data
- call rpar ; make answer for them
- mov al,ah ; length of packet
- mov ah,0
- mov pack.datlen,ax ; store length for spack
- mov trans.chklen,1 ; reply with 1 char checksum
- call pktsize ; report packet size
- mov ah,'Y' ; ack
- call spack ; answer them
- jmp rskp ; can't answer, forget this
- mov al,curchk ; restore checksum length
- mov trans.chklen,al
- call rrinit ; init variables for init
- cmp flags.destflg,2 ; file destination = screen?
- jne srvsnd0 ; ne = no
- mov flags.xflg,1 ; say receiving to screen
- jmp srvsnd1
- srvsnd0:call init ; setup display form
- srvsnd1:mov si,offset srvbuf ; work buffer
- mov byte ptr[si],5ch ; backslash
- inc si
- mov ah,gcd ; get current directory (path really)
- xor dl,dl ; use current drive
- int dos ; returns ds:si with asciiz path (no drive)
- mov si,offset srvbuf
- mov di,offset locfil ; destination is local override name
- call strcpy ; copy the path to local filename
- mov dx,di
- call strlen ; get length of string into cx
- mov di,cx ; length of local path
- mov locfil[di],5ch ; add backslash
- mov locfil[di+1],0 ; null terminator
- mov flags.nmoflg,1 ; say have override name (zaps external path)
- inc pack.pktnum ; count the send-init packet
- mov pack.state,'F' ; expecting file name about now
- call read12 ; join read code. changed from read2
- nop
- nop
- nop ; ignore errors
- mov flags.xflg,0
- jmp rskp ; and return for more
- srvsnd endp
-
- ; srvrcv - send a file to a distant kermit
-
- srvrcv proc near
- mov si,offset data ; received filename, asciiz from rpack
- test denyflg,getsflg ; command enabled?
- jz srrcv2 ; z = yes
- mov di,offset srvbuf ; local path
- mov si,offset rdbuf ; local filename
- mov dx,offset data ; local string
- call fparse ; split string
- mov si,offset rdbuf ; copy local filename to
- srrcv2: mov di,offset diskio.string ; destination
- call strcpy ; copy data to diskio.string
- mov pack.state,'R' ; remember state
- call send11 ; this should send it
- jmp rskp
- jmp rskp ; return in any case
- srvrcv endp
-
- ; srvgen - G generic server command dispatcher
- ;
- srvgen proc near
- mov al,data ; get 1st packet char
- srvge2: cmp al,'T' ; Type a file?
- jne srvge3 ; ne = no
- call srvtyp ; do the typing
- jmp rskp
- srvge3: cmp al,'D' ; do a directory?
- jne srvge4
- call srvdir ; do the directory command
- jmp rskp
- srvge4: cmp al,'E' ; do a file erase (delete)?
- jne srvge5
- call srvdel ; do the delete command
- jmp rskp
- srvge5: cmp al,'C' ; change working dir?
- jne srvge6 ; ne = no
- call srvcwd ; do it
- jmp rskp
- srvge6: cmp al,'U' ; do a space command?
- jne srvge7
- call srvspc ; do the space command
- jmp rskp
- srvge7: cmp al,'F' ; FIN?
- jne srvge8 ; ne = no
- jmp srvfin
- srvge8: cmp al,'L' ; LOGO or BYE?
- jne srvge9 ; ne = no
- call srvfin
- jmp short srvge8a ; permitted to exit Kermit
- nop
- jmp rskp ; stay active (command denied)
- srvge8a:mov flags.extflg,1 ; set exit flag
- ret ; leave server mode and Kermit
- srvge9: cmp al,'M' ; one line Message?
- jne srvge10 ; ne = no
- call srvsen
- jmp rskp
- srvge10:cmp al,'W' ; WHO?
- jne srvge11 ; ne = no
- call srvwho
- jmp rskp
- srvge11:cmp al,'H' ; Help?
- jne srvgex ; ne = no
- jmp srvhlp
- srvgex:
- ; mov bx,offset remms1 ; reply Unknown server command
- mcmsgb remms1, cremms1
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack
- jmp rskp
- srvgen endp
-
- ; srvfin - respond to remote host's Fin command. [jrd]
- srvfin proc near
- test denyflg,finflg ; command enabled?
- jz srfin1 ; z = yes
- ; mov bx,offset remms9 ; else give a message
- mcmsgb remms9, cremms9
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; back to local kermit
- jmp rskp ; stay in server mode
- srfin1:
- ; mov si,offset byemsg ; add brief msg of goodbye
- mcmsgsi byemsg, cbyemsg
-
-
- mov di,offset data ; packet's data field
- call strcpy ; copy msg to pkt
- mov dx,si ; strlen works on dx
- call strlen
- mov ah,'Y' ; reply with an ack
- mov pack.datlen,cx ; length
- mov trans.chklen,1 ; reply with 1 char checksum
- call pktsize ; report packet size
- call spack ; send it, expect no response
- nop ; ignore errors
- nop
- nop
- mov ax,100 ; wait 0.1 sec for client to settle
- call pcwait
- ret ; ret exits server mode
- srvfin endp
-
- ; srvcwd - handle other side's Remote CWD dirspec [jrd]
- srvcwd proc near
- test denyflg,cwdflg ; is command enabled?
- jz srcwd4 ; z = yes
- ; mov bx,offset remms9 ; else give a message
- mcmsgb remms9, cremms9
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; back to local kermit
- ret
- srcwd4: cmp pack.datlen,1 ; any data?
- je srcwd3 ; e = no
- mov cl,data+1 ; get the filename byte count
- sub cl,' ' ; ascii to numeric
- mov ch,0 ; set up counter
- cmp cl,0 ; anything there?
- jle srcwd3 ; le = no, an error
- mov si,offset data+2 ; received dir spec, from rpack
- mov di,offset srvbuf ; destination
- push es ; save es
- push ds
- pop es ; make es:di point to datas segment
- cld
- rep movsb ; copy data to srvbuf, cx chars worth
- pop es
- mov byte ptr [di],0 ; plant terminator
- mov dx,offset srvbuf ; for DOS
- mov ax,dx ; dir spec pointer for isfile
- cmp byte ptr [di-1],':' ; did user just type A: or similar?
- je srcwd1 ; e = yes, so skip directory part
- mov ah,chdir ; want to do change dir
- int dos
- jnc srcwd1 ; nc = ok
- srcwd3:
- ; mov bx,offset remms4 ; an error
- mcmsgb remms4, cremms4
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; send the bad news
- ret
- srcwd1: mov dl,data+3 ; see if drive given (look for :)
- cmp dl,':'
- jne srcwd2 ; ne = no drive
- mov dl,data+2
- and dl,5fH ; convert to upper case
- sub dl,'A' ; count A = 0 for seldsk call
- mov ah,seldsk
- int dos ; change disks
- jc srcwd3 ; c = an error
- inc dl ; now make A = 1 etc internally
- mov curdsk,dl ;and update internal current disk code
- srcwd2: mov ah,'Y' ; return an ack
- mov pack.datlen,0 ; no data
- mov trans.chklen,1 ; reply with 1 char checksum
- call pktsize ; report packet size
- call spack
- nop
- nop
- nop
- ret
- srvcwd endp
-
- ; srvtyp - handle other side's Remote Type filename request [jrd]
- ; expects "data" to hold Tcfilename where c = # bytes in filename
- srvtyp proc near
- cmp pack.datlen,1 ; any data in packet
- je srtyp2 ; e = no
- mov cl,data+1 ; get the filename byte count
- sub cl,' ' ; ascii to numeric
- mov ch,0 ; set up counter
- mov si,offset data+2 ; received filename, asciiz from rpack
- mov di,si
- add di,cx
- mov byte ptr [di],0 ; make string asciiz
- test denyflg,typflg ; paths permitted?
- jz srtyp1 ; z = yes, else use just filename part
- mov di,offset srvbuf ; local path
- mov si,offset rdbuf ; local filename
- mov dx,offset data+2 ; local string
- call fparse ; split string
- mov si,offset rdbuf ; copy local filename to
- srtyp1: mov di,offset diskio.string ; destination
- call strcpy ; do the copy
- mov ax,offset diskio.string ; pointer to filename, for isfile
- call isfile ; does it exist?
- jnc srtyp3 ; nc = yes
- srtyp2:
- ; mov bx,offset remms5 ; "No such file(s)"
- mcmsgb remms5, cremms5
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; send error message
- ret ; and exit
- srtyp3: mov flags.xflg,1 ; say use X packet rather than F pkt
- mov pack.state,'R' ; remember state
- call send11 ; this should send it
- nop
- nop
- nop
- mov flags.xflg,0 ; clear flag
- ret ; return in any case
- srvtyp endp
-
- ; serdir - handle other side's Remote Dir filespec(optional) request [jrd]
- srvdir proc near
- mov cx,0 ; assume no data in packet
- cmp pack.datlen,1 ; any data in the packet?
- je srdir4 ; e = no
- mov cl,data+1 ; get the filename byte count
- sub cl,' ' ; ascii to numeric
- mov ch,0 ; set up counter
- srdir4: mov di,offset data+2 ; received filespec, asciiz from rpack
- add di,cx
- mov byte ptr [di],0 ; make string asciiz
- test denyflg,dirflg ; paths permitted?
- jz srdir1 ; z = yes, else use just filename part
- mov di,offset srvbuf ; local path
- mov si,offset rdbuf ; local filename
- mov dx,offset data+2 ; local string
- call fparse ; split string
- mov si,offset rdbuf ; copy local filename to
- mov di,offset data+2 ; final filename
- call strcpy ; do the copy
- mov ax,di
- call isfile ; is/are there any such file?
- jc srdir1 ; c = there is none
- test byte ptr filtst.dta+21,1EH ; attr bits: is file protected?
- jz srdir1 ; z = not protected
- ; mov bx,offset remms8 ; "Protected or no such file(s)"
- mcmsgb remms8, cremms8
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; send error message
- ret ; and exit
-
- srdir1: mov di,offset srvbuf ; work area
- mov si,offset dirstr ; prepend "dir "
- call strcpy
- mov si,offset data+2 ; directory spec, asciiz
- mov di,offset srvbuf
- call strcat
- mov si,offset srvtmp ; add redirection tag of " >$kermit$.tmp"
- mov di,offset srvbuf
- call strcat
- mov si,offset srvbuf ; command pointer for crun
- call crun
- nop
- nop
- nop
- mov si,offset srvtmp+2 ; get name of temp file
- mov di,offset diskio.string ; destination
- call strcpy ; copy it there
- mov ax,di ; filename pointer for isfile
- call isfile ; did we make the temp file?
- jnc srdir3 ; nc = yes
- ; mov bx,offset remms6 ; "Could not create directory listing"
- mcmsgb remms6, cremms6
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; send the error message
- ret ; and exit
- srdir3: mov flags.xflg,1 ; say use X rather than F packet
- mov pack.state,'R' ; remember state
- call send11 ; this should send it
- nop
- nop
- nop
- mov flags.xflg,0 ; clear flag
- mov dx,offset diskio.string
- mov ah,del2 ; delete the file
- int dos
- ret ; return in any case
- srvdir endp
-
- ; serdel - handle other side's request of Remote Del filespec [jrd]
- srvdel proc near
- test denyflg,delflg ; command enabled?
- jz srvdel4 ; z = yes
- ; mov bx,offset remms9 ; else give a message
- mcmsgb remms9, cremms9
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; back to local kermit
- ret
-
- srvdel4:cmp pack.datlen,1 ; any data?
- je srdel1 ; e = no
- mov di,offset srvbuf ; work area
- mov si,offset delstr ; prepend "del "
- call strcpy
- mov dx,offset srvbuf
- call strlen
- add di,cx ; di points at terminator
- mov ax,di ; save pointer to incoming filespec
- mov cl,data+1 ; get the filename byte count
- sub cl,' ' ; ascii to numeric
- mov ch,0 ; set up counter
- cmp cl,0 ; anything there?
- jle srdel3 ; le = no
- mov si,offset data+2 ; received filespec, asciiz from rpack
- push es ; save es
- push ds
- pop es ; set es to datas segment
- cld
- rep movsb ; append data to srvbuf
- pop es ; restore es
- mov byte ptr [di],0 ; plant terminator
- call isfile ; is/are there any to delete?
- jc srdel1 ; c = there is none
- test byte ptr filtst.dta+21,1EH ; attr bits: is file protected?
- jz srdel2 ; z = not protected
- srdel1:
- ; mov bx,offset remms8 ; "Protected or no such file(s)"
- mcmsgb remms8, cremms8
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; send error message
- ret ; and exit
- srdel2: mov si,offset srvbuf ; set pointer for crun
- call crun
- nop
- nop
- nop
- srdel3: mov ah,'Y' ; return an ack
- mov pack.datlen,0 ; no data
- mov trans.chklen,1 ; reply with 1 char checksum
- call pktsize ; report packet size
- call spack
- nop
- nop
- nop
- ret
- srvdel endp
-
- ; serspc - handle other side's request of Remote Space [jrd]
- srvspc proc near
- test denyflg,spcflg ; is command enabled?
- jz srspc1 ; z = yes
- ; mov bx,offset remms9 ; else give a message
- mcmsgb remms9, cremms9
-
- mov trans.chklen,1 ; reply with 1 char checksum
- call errpack ; back to local kermit
- ret
- srspc1: mov dl,0 ; use current drive
- mov ah,36h ; get disk free space
- int dos ; ax = sectors/cluster
- cmp ax,0ffffh ; invalid drive indicator?
- jne srspc2 ; ne = no
- mov di,offset data
- ; mov si,offset spcmsg2 ; give Drive not ready message
- mcmsgsi spcmsg2, cspcmsg2
-
- call strcpy
- jmp short srspc3 ; send it
- srspc2: mul bx ; sectors/cluster * clusters = sectors
- mul cx ; bytes = sectors * bytes/sector
- mov di,offset data ; destination
- mov word ptr [di],0d0ah ; cr/lf
- mov word ptr[di+2],' ' ; space space
- add di,4 ; start number here
- call lnout ; convert number to asciiz in [di]
- ; mov si,offset spcmsg ; trailer of message
- mcmsgsi spcmsg2, cspcmsg2
-
- call strcat ; tack onto end of number part
- srspc3: mov trans.chklen,1 ; reply with 1 char checksum
- mov dx,offset data
- call strlen ; get data size into cx for doenc
- call doenc ; encode
- mov ah,'Y' ; reply with an ack
- call pktsize ; report packet size
- call spack ; send it, expect no response
- nop ; ignore errors
- nop
- nop
- ret
- srvspc endp
-
- ; srvwho - respond to remote host's WHO command. [jrd]
- srvwho proc near
- ; mov si,offset whomsg ; add brief msg of just us chickens
- mcmsgsi whomsg, cwhomsg
-
- mov di,offset data ; packet's data field
- call strcpy ; copy msg to pkt
- mov dx,si ; strlen works on dx
- call strlen
- mov trans.chklen,1 ; reply with 1 char checksum
- mov ah,'Y' ; reply with an ack
- mov pack.datlen,cx ; length
- call pktsize ; report packet size
- call spack ; send it, expect no response
- nop ; ignore errors
- nop
- nop
- ret
- srvwho endp
-
- ; srvmsg - respond to remote host's Message (Send) command
- ; show message on our screen. [jrd]
- srvsen proc near
- test denyflg,sndflg ; is command enabled?
- jnz srvsen1 ; nz = yes
- cmp pack.datlen,1 ; Any data in the packet?
- jbe srvsen1 ; e = no, just ack the message.
- cmp data,'M' ; Message packet?
- jne srvsen1 ; ne = no, ack and forget
- mov data,' ' ; remove the 'M'
- mov data+1,' ' ; and byte count field
- call dodec ; Decode data
- call ctlu ; clear the line
- mov dx,offset data+2 ; Where the reply is. (skip M and byte cnt)
- call prtasz ; Print it on the screen
- srvsen1:mov ah,'Y' ; reply with an ack
- mov pack.datlen,0 ; length
- mov trans.chklen,1 ; reply with 1 char checksum
- call pktsize ; report packet size
- call spack ; send it, expect no response
- nop ; ignore errors
- nop
- nop
- ret
- srvsen endp
-
-
- ; srvhos - handle other side's request of REM Host command-line. [jrd]
- ; We execute the command with STDOUT redirected to $kermit$.tmp and then
- ; read and transmit that file to the other end. No such file results in
- ; returning just an error msg ACK packet
- srvhos proc near
- test denyflg,hostflg ; command enabled?
- jz srvhos2 ; z = yes
- mov trans.chklen,1 ; reply with 1 char checksum
- ; mov bx,offset remms9 ; else give a message
- mcmsgb remms9, cremms9
-
- call errpack ; back to local kermit
- jmp rskp
-
- srvhos2:mov si,offset data ; received filename, asciiz from rpack
- mov di,offset srvbuf ; destination
- call strcpy ; copy data to srvbuf
- mov si,offset srvtmp ; add redirection tag of " >$kermit$.tmp"
- call strcat
- mov si,offset srvbuf ; si = pointer for crun
- call crun ; go do the command
- nop
- nop
- nop
- mov si,offset srvtmp+2 ; get name of temp file
- mov di,offset diskio.string ; destination
- call strcpy ; copy it to diskio.string
- mov ax,di ; filename pointer for isfile
- call isfile ; did we make the temp file?
- jnc srhos1 ; nc = yes
- mov trans.chklen,1 ; reply with 1 char checksum
- ; mov bx,offset remms10 ; else give a message
- mcmsgb remms10, cremms10
-
- call errpack ; back to local kermit
- call pktsize ; report packet size
- jmp rskp ; and exit
- srhos1: mov flags.xflg,1 ; say use X rather than F packet
- mov pack.state,'R' ; remember state
- call send11 ; this should send it
- nop
- nop
- nop
- mov flags.xflg,0 ; clear flag
- mov dx,offset diskio.string
- mov ah,del2 ; delete the temp file
- int dos
- jmp rskp ; return in any case
- srvhos endp
-
- ; Respond to other side's request of Remote Help. Write & read $kermit$.tmp
- ; Return rskp. [jrd]
- srvhlp proc near
- mov si,offset srvtmp+2 ; use filename of $kermit$.tmp
- mov di,offset diskio.string ; put name here
- call strcpy
- mov ah,creat2 ; create the file
- mov cx,0 ; attributes r/w
- mov dx,offset diskio.string ; use $kermit$.tmp name
- int dos
- jc srvhlp4 ; c = could not open
- mov diskio.handle,ax ; file handle
- ; mov dx,offset hlprem ; data to be sent, strlen uses dx
- mcmsg hlprem, chlprem
-
- call strlen ; put string length in cx
- mov ah,write2 ; write to file
- mov bx,diskio.handle
- int dos ; write the info
- pushf ; save carry bit
- mov ah,close2 ; close the file so we can reread it below
- mov bx,diskio.handle
- int dos
- popf ; recover carry bit
- jc srvhlp4 ; c = write error, tell remote user
- ; Send temporary file to remote screen
- mov flags.xflg,1 ; say use X rather than F packet
- mov pack.state,'R' ; remember state
- call send11 ; this should send it
- nop
- nop
- nop
- mov flags.xflg,0 ; clear flag
- mov dx,offset diskio.string ; filename
- mov ah,del2 ; delete the temp file
- int dos
- jmp rskp ; and return
-
- srvhlp4:mov trans.chklen,1 ; reply with 1 char checksum
- ; mov bx,offset remms3 ; else give a message
- mcmsgb remms3, cremms3
-
- call errpack ; back to local kermit
- call pktsize ; report packet size
- jmp rskp
- srvhlp endp
-
- ; srvini - init parms based on init packet
- srvini proc near
- mov bx,offset data
- mov ax,pack.datlen ; get number of data bytes
- call spar ; parse info
- call packlen ; this should really be part of spar, but..
- mov bx,offset data
- call rpar ; setup info about our reception
- push ax
- mov al,trans.chklen ; checksum length negotiated
- mov curchk,al ; use as new working length
- pop ax
- mov al,ah
- mov ah,0
- mov pack.datlen,ax ; set size of return info
- mov trans.chklen,1 ; reply with 1 char checksum
- mov ah,'Y'
- call pktsize ; report packet size
- call spack ; send the packet off
- nop
- nop
- nop
- mov al,curchk ; restore checksum length before proceeding
- mov trans.chklen,al
- jmp rskp ; and go succeed
- srvini endp
-
- ; This is the REMOTE command
-
- REMOTE PROC NEAR
- mov dx,offset remtab ; Parse a keyword from the REMOTE table
- ; mov bx,offset remhlp
- mcmsgb remhlp, cremhlp
-
- mov ah,cmkey
- call comnd
- jmp r
- call bx ; Call the appropriate routine
- jmp r ; Command failed
- jmp rskp
- REMOTE ENDP
-
- ; REMDIS - Get disk usage on remote system
-
- REMDIS PROC NEAR
- mov remcmd,'U' ; Disk usage command
- mov rempac,'G' ; Packet type = generic
- mov remlen,0 ; no text required
- jmp genric ; Execute generic Kermit command
- REMDIS ENDP
-
-
- ; REMHEL - Get help about remote commands
-
- REMHEL PROC NEAR
- mov remcmd,'H' ; Help
- mov rempac,'G' ; Packet type = generic
- mov remlen,0 ; no text required
- jmp genric ; Execute generic Kermit command
- REMHEL ENDP
-
- ; REMTYP - Type a remote file
-
- REMTYP PROC NEAR
- mov remcmd,'T' ; Type the file
- mov rempac,'G' ; Packet type = generic
- mov remlen,1 ; text required
- jmp genric
- REMTYP ENDP
-
- ; REMHOS - Execute a remote host command
-
- REMHOS PROC NEAR
- mov remcmd,' ' ; Don't need one
- mov rempac,'C' ; Packet type = remote command
- mov remlen,1 ; text required
- jmp genric
- REMHOS ENDP
-
- ; REMKER - Execute a remote Kermit command
-
- REMKER PROC NEAR
- mov remcmd,' ' ; Don't need one
- mov rempac,'K' ; Packet type = remote Kermit command
- mov remlen,1 ; text required
- jmp genric
- REMKER ENDP
-
- ; REMDIR - Do a directory
-
- REMDIR PROC NEAR
- mov remcmd,'D'
- mov rempac,'G' ; Packet type = generic
- mov remlen,0 ; no text required
- jmp genric
- REMDIR ENDP
-
- ; REMDEL - Delete a remote file
-
- REMDEL PROC NEAR
- mov remcmd,'E'
- mov rempac,'G' ; Packet type = generic
- mov remlen,1 ; text required
- jmp genric
- REMDEL ENDP
-
- ; REMCWD - Change remote working directory
-
- REMCWD PROC NEAR
- mov remcmd,'C'
- mov rempac,'G' ; Packet type = generic
- mov remlen,0 ; no text required
- jmp genric
- REMCWD ENDP
-
- ; REMLOGIN - LOGIN [username [password [account]]]
-
- REMLOGIN PROC NEAR
- mov remcmd,'I'
- mov rempac,'G' ; Packet type = generic
- mov remlen,0 ; no text required
- jmp genric
- REMLOGIN ENDP
-
- ; REMMSG - Send one line short message to remote screen. [jrd]
-
- REMMSG proc near
- mov remcmd,'M'
- mov rempac,'G'
- mov remlen,1 ; text required
- jmp genric
- REMMSG endp
-
- ; REMWHO - ask for list of remote logged on users [jrd]
-
- REMWHO proc near
- mov remcmd,'W'
- mov rempac,'G'
- mov remlen,0 ; no text required
- jmp genric
- REMWHO endp
-
- ; GENRIC - Send a generic command to a remote Kermit server
-
- GENRIC PROC NEAR
- mov bx,offset srvbuf ; Where to put the text
- mov temp,bx ; where field starts
- cmp rempac,'C' ; Remote Host command?
- je genra ; e = yes, no counted string(s)
- cmp rempac,'K' ; Remote Kermit command?
- je genra ; e = yes, no counted string(s)
- mov ah,remcmd ; get command letter
- mov [bx],ah ; store in buffer
- inc temp ; inc to data field
- add bx,2 ; Leave room for type and size
- genra: mov ah,cmtxt ; Parse arbitrary text up to a CR
- ; mov dx,offset genmsg ; In case they want help
- mcmsg genmsg, cgenmsg
-
- call comnd
- jmp r
- nop
- mov al,ah ; Don't forget the size
- mov ah,0
- mov cnt,ax ; Save it here
- add temp,ax ; point to next field
- cmp rempac,'C' ; Remote Host command?
- je genra3 ; e = yes, no counted string(s)
- cmp rempac,'K' ; Remote Kermit command?
- je genra3 ; e = yes, no counted string(s)
- cmp al,0 ; any text?
- je genra3 ; e = no
- add al,32 ; Do the tochar function
- mov srvbuf+1,al ; Size of first field
- inc temp ; include count byte
- genra3: cmp al,remlen ; got necessary command text?
- jae genra2 ; ae = yes
- mov ah,prstr
- ; mov dx,offset ermes1 ; need more info
- mcmsg ermes1, cermes1
-
- int dos
- or errlev,2 ; say cannot receive
- or fsta.xstatus,2 ; set status failed
- mov kstatus,2 ; global status
- jmp rskp
-
- genra2: mov flags.xflg,1 ; output coming to screen
- cmp rempac,'K' ; Remote Kermit command?
- jne genraa
- jmp genr0 ; e = yes
- genraa: cmp rempac,'C' ; Remote host command?
- jne genrb
- jmp genr0 ; No, skip this part
-
- genrb:
- cmp remcmd,'C' ; Change working directory?
- je genrf ; e = yes, ask for password
- cmp remcmd,'I' ; remote login command?
- je genrd ; e = yes
- jmp genr0 ; neither so no extra prompts here
-
- genrd: cmp cnt,0 ; have user name already?
- jne genrf ; ne = yes
- ; mov dx,offset user ; prompt for username
- mcmsg user, cuser
-
- call prompt
- mov bx,offset srvbuf+1 ; skip command letter
- mov temp,bx ; start of field
- call input ; Read text
- jcxz genr0 ; z = none
- mov temp,bx ; point to next data field
-
- genrf:
- ; mov dx,offset password ; Get optional password
- mcmsg password, cpassword
-
- call prompt
- mov bx,temp ; Where to put the password
- mov comand.cmquiet,1 ; turn on quiet mode
- call input ; Read in the password
- mov comand.cmquiet,0 ; turn off quiet mode
- jcxz genr0 ; z = no text, do not add field
- mov temp,bx ; point to next data field
- ;
- cmp remcmd,'I' ; remote login command?
- jne genr0 ; ne = no
- ; mov dx,offset account ; get optional account ident
- mcmsg account, caccount
-
- call prompt
- mov bx,temp ; Where this field starts
- call input ; Read in text
- jcxz genr0 ; z = no text, do not add field
- mov temp,bx ; point to next data field
- ; All fields completed
- genr0: mov ax,temp ; pointer to next field
- sub ax,offset srvbuf ; minus start of buffer = data length
- mov cnt,ax ; remember size here
- cmp flags.cxzflg,'C' ; Control-C entered?
- jne genr0a ; ne = no
- ret ; return failure
-
- genr0a: mov kstatus,0 ; global status
- mov pack.numtry,0 ; Initialize count
- call ipack ; Send init parameters
- jmp genr2
- nop ; Make it 3 bytes long
- mov ah,trans.chklen
- mov curchk,ah ; Save desired checksum length
- mov trans.chklen,1 ; Use 1 char for server functions
- mov pack.numrtr,0 ; No retries yet
- genr1: cmp pack.state,'A' ; Did the user type a ^C?
- je genr2x
- mov ah,pack.numtry
- cmp ah,maxtry ; Too many tries?
- jl genr3 ; Nope, keep trying
- genr2: mov ah,prstr
- ; mov dx,offset erms18 ; Print error msg and fail
- mcmsg erms18, cerms18
-
- int dos
- genr2x: mov ah,curchk
- mov trans.chklen,ah ; Restore
- mov flags.xflg,0 ; reset screen output flag before leaving
- xor ax,ax ; tell statistics this was a read
- or errlev,4 ; DOS error level, failure of REMote cmd
- mov fsta.xstatus,4 ; set status
- mov kstatus,4 ; global status
- jmp rskp
- genr3: push es ; Prepare to put string into packet
- push ds
- pop es
- mov si,offset srvbuf ; Move from here
- mov di,offset data ; to here
- mov cx,cnt ; Move this many characters
- cld
- rep movsb ; Perform the string move
- pop es
- mov ax,cnt
- mov pack.datlen,ax ; How much data to send
- mov cx,ax ; Size of data
- call doenc ; Encode it
- inc pack.numtry ; Increment number of trials
- mov trans.chklen,1 ; use block check 1 to server
- mov pack.seqnum,0 ; Packet number 0
- mov ah,rempac ; Packet type
- call pktsize ; report packet size
- call spack ; Send the packet
- jmp genr2 ; Tell user we can't do it
- nop
- call rpack ; Get ACK (w/o screen stuff)
- jmp genr3a ; Got a NAK - try again
- nop
- jmp genr3b ; Ok
-
- genr3a: push ax
- mov ah,curchk
- mov trans.chklen,ah ; Restore after reception
- pop ax
- jmp genr1 ; NAK, try again
-
- genr3b: push ax ; Ok
- mov ah,curchk
- mov trans.chklen,ah ; Restore after reception
- pop ax
- cmp ah,'Y' ; Is all OK?
- jne genr4
- cmp pack.datlen,0 ; Any data in the ACK?
- je genr31 ; Nope - just return.
- call dodec ; Decode data
- mov di,offset data ; Where the reply is
- mov cx,pack.datlen ; How much data we have
- jcxz genr31 ; z = nothing
- mov ah,prstr
- mov dx,offset crlf ; start with cr/lf
- int dos
- call prtscr ; Print it on the screen
- genr31: mov flags.xflg,0 ; reset screen output flag before leaving
- jmp rskp ; And we're done.
- genr4: cmp ah,'X' ; Text packet?
- je genr5
- cmp ah,'S' ; Handling this like a file?
- jne genr6
- mov pack.state,'R' ; Set the state
- mov bx,offset rin21 ; Where to go to
- jmp genr51 ; Continue
- genr5: mov pack.state,'F'
- call dodec ; Decode data
- mov bx,offset rfile3 ; Jump to here
- genr51: mov flags.xflg,1 ; Remember we saw an "X" packet
- push ax
- mov ah,prstr
- mov dx,offset crlf ; for some systems
- int dos
- pop ax ; keep packet type in ah
- mov pack.numtry,0
- mov pack.numrtr,0
- mov pack.numpkt,0
- mov pack.pktnum,0
- call begtim ; start next statistics group
- call bx ; Handle it almost like filename
- call read2 ; Receive the rest
- jmp r ; Oops, we failed
- nop
- jmp rskp ; Done OK
- genr6: cmp ah,'E' ; Error packet?
- je genr6x ; e = yes
- jmp genr1 ; Try again
- genr6x: call dodec ; Decode data
- call error1 ; Print the error messge
- ;;;; call serrst
- mov flags.xflg,0 ; reset screen output flag before leaving
- jmp rskp ; And return
- GENRIC ENDP
-
- ; Send "I" packet with transmission parameters
-
- IPACK PROC NEAR
- call serini ; Initialize port
- jc ipk0x ; c = failure
- call ihosts ; initialize the host
- mov pack.pktnum,0 ; Use packet number 0
- mov pack.numtry,0 ; Number of retries
- mov pack.numrtr,-1 ; no retries (incremented below)
- ipk0: call updrtr
- cmp pack.state,'A' ; Did user type a ^C?
- je ipk0x ; e = yes
- push dx
- mov dl,imxtry
- cmp pack.numtry,dl ; Reached our limit?
- pop dx
- jl ipk1 ; l = no
- ipk0x: ret ; Yes, so we fail
- ipk1: inc pack.numtry ; Save the updated number of tries
- mov ah,dtrans.ebquot ; default 8 bit quote, needed with parity
- mov trans.ebquot,ah ; save as active mode
- mov bx,offset data ; Get a pointer to our data block
- call rpar ; Set up the parameter information
- xchg ah,al
- mov ah,0
- mov pack.datlen,ax ; Save the number of arguments
- mov pack.seqnum,0 ; Use packet number 0
- mov ah,dtrans.seol ; restore default end-of-line char
- mov trans.seol,ah
- mov ah,trans.chklen
- mov curchk,ah ; Save real value
- mov trans.chklen,1 ; One char for server function
- call pktsize ; report packet size
- mov ah,'I' ; "I" packet
- call spack ; Send the packet
- jmp ipk4
- nop
- call rpack ; Get a packet
- jmp ipk4 ; Try again
- nop
- push ax
- mov ah,curchk
- mov trans.chklen,ah ; Reset
- pop ax
- cmp ah,'Y' ; ACK?
- jne ipk3 ; If not try next
- mov ax,pack.pktnum ; Get the packet number
- cmp ax,pack.seqnum ; Is it the right packet number?
- je ipk2
- jmp ipk0 ; If not try again
- ipk2: mov ax,pack.datlen ; Get the number of pieces of data
- mov bx,offset data ; Pointer to the data
- ipk2a: call spar ; Read in the data
- mov ah,trans.chklen
- mov curchk,ah ; This is what we decided on
- call packlen ; Get max send packet size
- mov pack.numtry,0 ; Reset the number of tries
- jmp rskp
- ipk3: cmp ah,'N' ; NAK?
- jne ipk3y ; Yes, try again
- jmp ipk0
- ipk3y: cmp ah,'E' ; Is it an error packet
- je ipk3x
- jmp ipk0 ; Trashed data.
- ipk3x: mov ax,0 ; Other side doesn't know about "I" packet
- ; force defaults (zero length response)
- jmp ipk2a ; to use lowest common denominator
- ipk4: mov ah,curchk
- mov trans.chklen,ah ; Reset.
- cmp flags.cxzflg,0 ; did user say quit?
- jne ipk5 ; ne = yes, quit
- jmp ipk0 ; Keep trying
- ipk5: ret
- IPACK ENDP
-
- ; Returns CX the count of characters read
- ; BX the updated pointer to the input buffer
- ; input buffer = <ascii data length count byte>textstring
- INPUT PROC NEAR
- mov inpbuf,bx ; Where to put byte count
- inc bx ; skip over count byte
- mov dx,0 ; help, none
- mov ah,cmtxt ; get text with embedded whitespace
- call comnd
- jmp r
- nop
- mov al,ah ; length of text
- mov ah,0
- mov cnt,ax ; save here
- input1: push bx
- mov bx,inpbuf
- mov [bx],al ; store count byte
- add byte ptr [bx],32 ; convert to ascii
- pop bx ; return pointer to next free byte
- mov cx,cnt ; return byte count
- ret
- INPUT ENDP
-
-
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ret
- RSKP ENDP
-
- ; Jumping here is the same as a ret
-
- R PROC NEAR
- ret
- R ENDP
-
- code ends
- end
-